#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <queue>
struct pos{
    int x,y;
    int val;
};
static char graph[101][101],visit[100][101];
static pos L{-1,0,0}, R{1,0,0}, U{0,-1,0}, D{0,1,0};
void display(std::queue<pos> q)
{
    while (!q.empty()) {
        std::cout<<"("<<q.front().x<<","<<q.front().y<<","<<q.front().val<<")->";
        q.pop();
    }
}
inline bool goNext(pos to, std::queue<std::queue<pos>> &s, std::queue<pos> &path, int m, int n)//m->y,n->x
{
    pos last = path.back();
    int nx=last.x+to.x,ny=last.y+to.y;
    if(visit[ny][nx]==0){
        if(graph[ny][nx]!='X')
        {
            visit[ny][nx]=1;
            std::queue<pos> tp = path;
            if(graph[ny][nx]=='.')
            {
                pos np{nx,ny,last.val+1};
                tp.push(np);
                if(nx==n-1&&ny==m-1){
                    s.push(tp);
                    return true;
                }
            }else
            {
                pos np{nx,ny, last.val+graph[ny][nx]-'0'+1};
                tp.push(np);
                if(nx==n-1&&ny==m-1){
                    s.push(tp);
                    return true;
                }
            }
            s.push(tp);
        }
    }
    return false;
}
std::queue<pos> find(int m, int n, bool &hasPath)
{
    std::queue<pos> path;
    std::queue<std::queue<pos>> s1;
    path.push(pos{0,0,1});
    visit[0][0]=1;
    s1.push(path);
    int len=1;
    hasPath=false;
    while (s1.size()!=0) {
        len++;
        int size = s1.size();
        bool hasNext = false;
        std::queue<std::queue<pos>> s2;
        for(int i = 0; i < size; i++)
        {
            path=s1.front();
            pos last = path.back();
            //fight with monster?
            if(last.val>=len)
            {
                s2.push(path);
                s1.pop();
                continue;
            }
            //up
            if(last.y>0)
            {
                if(goNext(U, s2, path,m,n)){
                    hasPath=true;
                    return s2.back();
                }
            }
            //down
            if(last.y<m-1)
            {
                if(goNext(D, s2, path,m,n)){
                    hasPath=true;
                    return s2.back();
                }
            }
            //left
            if(last.x>0){
                if(goNext(L, s2, path,m,n)){
                    hasPath=true;
                    return s2.back();
                }
            }
            //right
            if(last.x<n-1){
                if(goNext(R, s2, path,m,n)){
                    hasPath=true;
                    return s2.back();
                }
            }

            s1.pop();

        }

        s1=s2;

    }
    return path;
}
int main()
{
    int m,n;
    char str[101];
    while (std::cin>>m>>n) {
        memset(visit, 0, 100*101);
        for(int i = 0; i < m; i++)
        {
            std::cin>>str;
            for(int j = 0; j < n; j++)
            {
                graph[i][j]=str[j];
            }
        }
        bool hasPath;
        std::queue<pos> path = find(m,n,hasPath);
        if(!hasPath)
            std::cout<<"God please help our poor hero.\n";
        else{
            int t = 0;
            pos p1 = path.front(),p2;
            std::cout<<"It takes "<<path.back().val-1<<" seconds to reach the target position, let me show you the way.\n";
            path.pop();
            while (!path.empty()) {
                p2 = path.front();
                std::cout<<++t<<"s:("<<p1.y<<","<<p1.x<<")->("<<p2.y<<","<<p2.x<<")\n";
                if(graph[p2.y][p2.x]!='.')
                {
                    for(int i = 0; i < graph[p2.y][p2.x]-'0'; i++)
                    {
                        std::cout<<++t<<"s:FIGHT AT ("<<p2.y<<","<<p2.x<<")\n";
                    }
                }
                p1=p2;
                path.pop();


            }
        }
        std::cout<<"FINISH\n";
    }

    return 0;
}
